/**
* 版权声明：厦门睿商网络科技有限公司 版权所有 违者必究
* 日    期：2020-02-20
*/
package com.rzico.order.service;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.rzico.account.entity.Payable;
import com.rzico.account.entity.Payment;
import com.rzico.account.entity.Receivable;
import com.rzico.account.model.Attach;
import com.rzico.account.service.PayableService;
import com.rzico.account.service.ReceivableService;
import com.rzico.base.BaseMapper;
import com.rzico.base.impl.BaseServiceImpl;
import com.rzico.basics.entity.*;
import com.rzico.basics.service.*;
import com.rzico.core.entity.SysUser;
import com.rzico.core.service.SysSequenceService;
import com.rzico.core.service.SysUserService;
import com.rzico.exception.CustomException;
import com.rzico.order.entity.*;
import com.rzico.order.mapper.WarehouseMapper;
import com.rzico.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.rzico.order.enumx.*;

import java.math.BigDecimal;
import java.util.*;

import static com.rzico.order.enumx.AllocateShippingStatusEnum.ALLOCATE_SHIPPING_HAS_OUT;

/**
 * <pre>
 * 出入库单业务类
 * </pre>
 *
 * @author Rzico Boot
 * @version 1.0
 */
@Service
public class WarehouseService extends BaseServiceImpl<Warehouse, String> {

    protected Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private WarehouseMapper warehouseMapper;

    @Autowired
    private SysSequenceService sysSequenceService;

    @Autowired
    private ProductService productService;

    @Autowired
    private WarehouseItemService warehouseItemService;

    @Autowired
    private WarehouseStockService warehouseStockService;

    @Autowired @Lazy
    private OrderService orderService;

    @Autowired
    private ShippingService shippingService;

    @Autowired
    private ReturnService returnService;

    @Autowired @Lazy
    private AllocateService allocateService;

    @Autowired
    private OrderItemService orderItemService;

    @Autowired @Lazy
    private PurchaseService purchaseService;

    @Autowired
    private PurchaseItemService purchaseItemService;

    @Autowired
    private AllocateItemService allocateItemService;

    @Autowired
    private OrderPlanService orderPlanService;

    @Autowired
    private MemberService memberService;

    @Autowired
    private PayableService payableService;

    @Autowired
    private ReceivableService receivableService;

    @Override
    public BaseMapper<Warehouse, String> getMapper() {
        return warehouseMapper;
    }

    /**
     * 构造参数
     * @param warehouse
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public int insertWarehouse(Warehouse warehouse) {

        warehouse.setSn(sysSequenceService.generate("order"));
        if (null == warehouse.getStatus()){
            //默认未确认
            warehouse.setStatus(WarehouseStatusEnum.WAREHOUSE_STATUS_UNCONFIRM.getId());
        }

        warehouse.setDeleted(false);
        warehouse.setSPrint(0);
        List<WarehouseItem> itemsList = new ArrayList<>();
        for (WarehouseItem warehouseItem : warehouse.getItemList()){
            initWarehouseItem(warehouseItem);
//            if (!warehouseItem.getSubType().equals(1) && !warehouseItem.getSubType().equals(0) ) {
//                throw new CustomException("虚拟商品不能出入库");
//            }
            //冗余存储
            warehouseItem.setShopId(warehouse.getShopId());
            warehouseItem.setEnterpriseId(warehouse.getEnterpriseId());
            itemsList.add(warehouseItem);
        }
        warehouse.setItemList(itemsList);
        warehouse.setSubPrice(warehouse.calculateSubPrice());
        warehouse.setSubQuantity(warehouse.calculateSubQuantity());

        return insertUseGeneratedKeys(warehouse);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertUseGeneratedKeys(Warehouse warehouse) {
        int affectCount = super.insertUseGeneratedKeys(warehouse);
        if (affectCount > 0){
            for (WarehouseItem warehouseItem : warehouse.getItemList()){
                Product product = productService.selectByPrimaryKey(warehouseItem.getProductId());
                warehouseItem.setSubType(product.getSubType());
                warehouseItem.setMainProductId(product.getMainProductId());
                warehouseItem.setMainProductQuantity(warehouseItem.getQuantity().abs().multiply(product.getUnitRate()).setScale(2, BigDecimal.ROUND_HALF_UP));
                warehouseItem.setWarehouseId(warehouse.getId());
                warehouseItem.setEnterpriseId(warehouse.getEnterpriseId());
            }
            warehouseItemService.insertUseGeneratedKeyList(warehouse.getItemList());
        }
        return affectCount;
    }

    @Transactional(rollbackFor = Exception.class)
    public int updateWarehouse(Warehouse warehouse){
        Warehouse warehouse1 = selectByPrimaryKey(warehouse.getId());
        if (!warehouse1.getStatus().equals(WarehouseStatusEnum.WAREHOUSE_STATUS_UNCONFIRM.getId())){
            throw new CustomException("单据已不可修改");
        }
        BigDecimal totalPrice = BigDecimal.ZERO;
        BigDecimal totalQuantity = BigDecimal.ZERO;
        //不可修改字段
        warehouse.setStatus(null);
        warehouse.setSn(null);

        /**
         * 3、原订单商品明细与编辑之后的商品明细对比
         * result = 0, insert
         * result = 1, update
         * result = 2, delete
         */
        WarehouseItem paramsItem = new WarehouseItem();
        paramsItem.setWarehouseId(warehouse.getId());
        List<WarehouseItem> sourceOrderItemList = warehouseItemService.select(paramsItem);

        List<WarehouseItem> targetOrderItemList = warehouse.getItemList();
        for (WarehouseItem targetOrderItem : targetOrderItemList){
            initWarehouseItem(targetOrderItem);
//            if (!targetOrderItem.getSubType().equals(1) && !targetOrderItem.getSubType().equals(0) ) {
//                throw new CustomException("虚拟商品不能出入库");
//            }
            if (targetOrderItem.getId()==null) {

                Product product = productService.selectByPrimaryKey(targetOrderItem.getProductId());
                targetOrderItem.setMainProductId(product.getMainProductId());
                targetOrderItem.setMainProductQuantity(targetOrderItem.getQuantity().multiply(product.getUnitRate()).setScale(2, BigDecimal.ROUND_HALF_UP));
                targetOrderItem.setEnterpriseId(warehouse.getEnterpriseId());
                targetOrderItem.setShopId(warehouse.getShopId());
                targetOrderItem.setWarehouseId(warehouse.getId());
                warehouseItemService.insertUseGeneratedKeys(targetOrderItem);
            } else {
                for (WarehouseItem sourceOrderItem : sourceOrderItemList){
                    if (targetOrderItem.getId().equals(sourceOrderItem.getId())){
                        sourceOrderItemList.remove(sourceOrderItem);
                        break;
                    }
                }
                //获取商品的最小单位的商品编号
                Product product = productService.selectByPrimaryKey(targetOrderItem.getProductId());
                targetOrderItem.setMainProductId(product.getMainProductId());
                targetOrderItem.setMainProductQuantity(targetOrderItem.getQuantity().multiply(product.getUnitRate()).setScale(2, BigDecimal.ROUND_HALF_UP));
                targetOrderItem.setShopId(warehouse.getShopId());
                targetOrderItem.setWarehouseId(warehouse.getId());
                warehouseItemService.updateByPrimaryKeySelective(targetOrderItem);
            }
        }

        //4、删除未匹配中的数据
        if (null != sourceOrderItemList && sourceOrderItemList.size() > 0){
            for (WarehouseItem orderItem : sourceOrderItemList){
                warehouseItemService.deleteByPrimaryKey(orderItem.getId());
            }
        }

        warehouse.setSubPrice(warehouse.calculateSubPrice());
        warehouse.setSubQuantity(warehouse.calculateSubQuantity());
        return super.updateByPrimaryKeySelective(warehouse);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteByIds(Object[] ids) {
        int rw = 0;
        for (Object id:ids) {
            Warehouse warehouse = selectByPrimaryKey(id);
            if (!warehouse.getStatus().equals(WarehouseStatusEnum.WAREHOUSE_STATUS_CANCEL.getId()) && !warehouse.getStatus().equals(WarehouseStatusEnum.WAREHOUSE_STATUS_UNCONFIRM.getId())) {
                throw new CustomException("无权限删除");
            }
            warehouse.setDeleted(true);
            rw = rw + super.updateByPrimaryKeySelective(warehouse);
        }
        return rw;
    }

    @Transactional(rollbackFor = Exception.class)
    public void confirm(Long id){

        Warehouse warehouse = selectByPrimaryKey(id);
        if (!warehouse.getStatus().equals(WarehouseStatusEnum.WAREHOUSE_STATUS_UNCONFIRM.getId())){
            throw new CustomException("订单状态非未确认");
        }

        warehouse.setStatus(1);
        int affectCount = super.updateByPrimaryKeySelective(warehouse);
        if (affectCount > 0){
            WarehouseItem param = new WarehouseItem();
            param.setWarehouseId(warehouse.getId());
            List<WarehouseItem> list = warehouseItemService.select(param);
            warehouse.setItemList(list);
            for (WarehouseItem warehouseItem : warehouse.sortItemList()){
                warehouseStockService.preHandle(warehouse.getWarehouseType(), warehouseItem);
            }
        }

        //回写各种原单据的发货、退货数量
        if (null != warehouse.getOrderId()){
            writeOrderQuantity(warehouse);
        }

        if (warehouse.getOrderPlanId()==null) {
            orderPlanService.addWarehouse(warehouse);
        }

        if (warehouse.getWarehouseType().equals(WarehouseTypeEnum.WAREHOUSE_TYPE_SALE_OUT.getId())) {
            insertShipping(warehouse,warehouse.getSn());
        }
        if (warehouse.getWarehouseType().equals(WarehouseTypeEnum.WAREHOUSE_TYPE_SALE_IN.getId())) {
            insertReturn(warehouse,warehouse.getSn());
        }

        //生成应收应付账款
        insertPayableOrReceivable(warehouse);

    }


    public void insertPayableOrReceivable(Warehouse warehouse){
        WarehouseTypeEnum warehouseTypeEnum = WarehouseTypeEnum.getById(warehouse.getWarehouseType());
        switch (warehouseTypeEnum){
            case WAREHOUSE_TYPE_PURCHASE_IN:
                //采购入库类型，有原单号的不生成，无原单号的生成应收款(即直接开入库单的才会生成应收款)
                if (null == warehouse.getOrderId()){
                    Payable payable = new Payable();
                    payable.setAmount(warehouse.getSubPrice());
                    payable.setAmountPaid(BigDecimal.ZERO);
                    //0应付款  1应退款
                    payable.setType(0);
                    payable.setDeleted(false);
                    payable.setStatus(0);
                    payable.setSupplierId(warehouse.getSupplierId());
                    payable.setEnterpriseId(warehouse.getEnterpriseId());
                    payable.setWarehouseId(warehouse.getId());
                    payable.setOfficeId(warehouse.getOfficeId());
                    payable.setOrderSn(warehouse.getSn());
                    payable.setOrderId(warehouse.getId());
                    payable.setOrderType(1);
                    payableService.insert(payable);
                }

                break;
            case WAREHOUSE_TYPE_PURCHASE_OUT:
                //采购退货类型，无论如何都会生成负的应付款
                Payable payable2 = new Payable();
                payable2.setAmount(warehouse.getSubPrice().multiply(BigDecimal.valueOf(-1)));
                payable2.setAmountPaid(BigDecimal.ZERO);
                //0应付款  1应退款
                payable2.setType(1);
                payable2.setDeleted(false);
                payable2.setStatus(0);
                payable2.setSupplierId(warehouse.getSupplierId());
                payable2.setEnterpriseId(warehouse.getEnterpriseId());
                payable2.setOrderSn(warehouse.getSn());
                payable2.setOrderId(warehouse.getId());
                payable2.setOrderType(2);
                payable2.setWarehouseId(warehouse.getId());
                payable2.setOfficeId(warehouse.getOfficeId());

                payableService.insert(payable2);
                break;
            case WAREHOUSE_TYPE_SALE_OUT:
                //销售出库，有原单号不生成，没有原单号的生成应收款
                if (null == warehouse.getOrderId()){
                    Receivable receivable = new Receivable();
                    receivable.setAmount(warehouse.getSubPrice());
                    receivable.setAmountPaid(BigDecimal.ZERO);
                    receivable.setQuantity(0);
                    receivable.setQuantityPaid(0);
                    Member member = memberService.selectByPrimaryKey(warehouse.getMemberId());
                    if ("debtPayPlugin".equals(member.getPaymentPluginId())) {
                        receivable.setPaymentPluginId("debtPayPlugin");
                        receivable.setPaymentPluginName("月结");
                    } else {
                        receivable.setPaymentPluginId("cashPayPlugin");
                        receivable.setPaymentPluginName("现金");
                    }
                    //账款类型(0.应收款,1.应退款)
                    receivable.setType(0);
                    receivable.setDeleted(false);
                    receivable.setStatus(0);
                    receivable.setMemberId(warehouse.getMemberId());
                    receivable.setEnterpriseId(warehouse.getEnterpriseId());
                    receivable.setWarehouseId(warehouse.getId());
                    receivable.setOfficeId(warehouse.getOfficeId());

                    receivable.setOrderSn(warehouse.getSn());
                    receivable.setOrderId(warehouse.getId());
                    receivable.setOrderType(1);

                    receivableService.insert(receivable);
                }

                break;
            case WAREHOUSE_TYPE_SALE_IN:
                if (null == warehouse.getAskforId()) {
                    Receivable receivable2 = new Receivable();
                    receivable2.setAmount(warehouse.getSubPrice());
                    receivable2.setAmountPaid(BigDecimal.ZERO);
                    receivable2.setQuantity(0);
                    receivable2.setQuantityPaid(0);
                    Member member = memberService.selectByPrimaryKey(warehouse.getMemberId());
                    if ("debtPayPlugin".equals(member.getPaymentPluginId())) {
                        receivable2.setPaymentPluginId("debtPayPlugin");
                        receivable2.setPaymentPluginName("月结");
                    } else {
                        receivable2.setPaymentPluginId("cashPayPlugin");
                        receivable2.setPaymentPluginName("现金");
                    }

                    //账款类型(0.应收款,1.应退款)
                    receivable2.setType(1);
                    receivable2.setDeleted(false);
                    receivable2.setStatus(0);
                    receivable2.setMemberId(warehouse.getMemberId());
                    receivable2.setEnterpriseId(warehouse.getEnterpriseId());
                    receivable2.setWarehouseId(warehouse.getId());
                    receivable2.setOfficeId(warehouse.getOfficeId());

                    receivable2.setOrderSn(warehouse.getSn());
                    receivable2.setOrderId(warehouse.getId());
                    receivable2.setOrderType(2);

                    receivableService.insert(receivable2);
                }
                break;
            default:
                break;

        }
    }

    @Transactional(rollbackFor = Exception.class)
    public int audit(Long id){
        Warehouse warehouse = selectByPrimaryKey(id);
        //审核通过
        warehouse.setStatus(WarehouseStatusEnum.WAREHOUSE_STATUS_COMPLETE.getId());
        int affectCount = super.updateByPrimaryKeySelective(warehouse);
        if (affectCount > 0){
            WarehouseItem param = new WarehouseItem();
            param.setWarehouseId(warehouse.getId());
            List<WarehouseItem> list = warehouseItemService.select(param);
            warehouse.setItemList(list);
            for (WarehouseItem warehouseItem : warehouse.sortItemList()){
                warehouseStockService.afterCompletion(warehouse.getWarehouseType(), warehouseItem);
            }

            if (warehouse.getOrderPlanId()!=null) {
                OrderPlan orderPlan = orderPlanService.selectByPrimaryKey(warehouse.getOrderPlanId());
                orderPlan.setStatus(2);
                orderPlanService.updateByPrimaryKeySelective(orderPlan);
            }

        }


        return affectCount;
    }

/*    public void processOn(Warehouse warehouse){
        WarehouseTypeEnum warehouseTypeEnum = WarehouseTypeEnum.getById(warehouse.getWarehouseType());
        switch (warehouseTypeEnum) {
            case WAREHOUSE_TYPE_SALE_IN:

            case WAREHOUSE_TYPE_ALLOCATE_OUT :
                //调拨出库，回写调拨单出库状态
                Allocate allocateOut = new Allocate();
                allocateOut.setId(warehouse.getOrderId());
                allocateOut.setShippingStatus(AllocateShippingStatusEnum.ALLOCATE_SHIPPING_HAS_OUT.getId());
                allocateOut.setWarehouseId(warehouse.getId());
                allocateOut.setFlag("out");
                sendAllocateMq(allocateOut);
                //调拨出库，同时生成调拨入库
                insertWareHouseByAllocate(warehouse);
                break;
            case WAREHOUSE_TYPE_ALLOCATE_IN :
                Allocate allocateIn = new Allocate();
                allocateIn.setId(warehouse.getOrderId());
                allocateIn.setShippingStatus(AllocateShippingStatusEnum.ALLOCATE_SHIPPING_HAS_IN.getId());
                allocateIn.setFlag("in");
                //此处存放warehouseId，用于更新调拨单的入库商品数量(receiviedQuantity)
                allocateIn.setWarehouseId(warehouse.getId());
                sendAllocateMq(allocateIn);
                //todo 更新调拨单入库数量

                break;
            default:
                break;
        }
    }*/


    @Transactional(rollbackFor = Exception.class)
    public int disAudit(Long id){
        //1、判断单据是否存在
        Warehouse warehouse = selectByPrimaryKey(id);
        if (null == warehouse){
            throw new CustomException("单据不存在");
        }
        //2、非已完成不可弃审
        if (!warehouse.getStatus().equals(WarehouseStatusEnum.WAREHOUSE_STATUS_COMPLETE.getId())){
            throw new CustomException("单据状态非已完成,不可弃审!");
        }
        //3、更新单据状态，并处理库存数据
        warehouse.setStatus(WarehouseStatusEnum.WAREHOUSE_STATUS_CONFIRM.getId());
        int affectCount = super.updateByPrimaryKeySelective(warehouse);
        if (affectCount > 0){
            WarehouseItem param = new WarehouseItem();
            param.setWarehouseId(warehouse.getId());
            List<WarehouseItem> list = warehouseItemService.select(param);
            warehouse.setItemList(list);
            for (WarehouseItem warehouseItem : warehouse.sortItemList()){
                warehouseStockService.preCancelHandle(warehouse.getWarehouseType(), warehouseItem);
            }


            if (warehouse.getOrderPlanId()!=null) {
                OrderPlan orderPlan = orderPlanService.selectByPrimaryKey(warehouse.getOrderPlanId());
                orderPlan.setStatus(1);
                orderPlanService.updateByPrimaryKeySelective(orderPlan);
            }

        }
        return affectCount;
    }

    @Transactional(rollbackFor = Exception.class)
    public int cancel(Long id){

        int affectCount = 0;
        //1、判断单据是否存在
        Warehouse warehouse = selectByPrimaryKey(id);
        if (null == warehouse){
            throw new CustomException("单据不存在");
        }
        //2、非已确认，不可作废
        if (!warehouse.getStatus().equals(WarehouseStatusEnum.WAREHOUSE_STATUS_CONFIRM.getId())){
            throw new CustomException("单据不可作废");
        }

        if (warehouse.getOrderPlanId()!=null) {
            throw new CustomException("单据不可作废");
        }

        //3、减去各种单据在出入库单确认方法里writeOrderQuantity的数据
        undoWriteOrderQuantity(warehouse);

        orderPlanService.delWarehouse(warehouse);

        //4、更新单据状态，并处理库存数据
        warehouse.setStatus(WarehouseStatusEnum.WAREHOUSE_STATUS_CANCEL.getId());
        affectCount = super.updateByPrimaryKeySelective(warehouse);
        if (affectCount > 0){
            //已确认的出库单才操作了库存，才需要处理库存
            WarehouseItem param = new WarehouseItem();
            param.setWarehouseId(warehouse.getId());
            List<WarehouseItem> list = warehouseItemService.select(param);
            warehouse.setItemList(list);
            for (WarehouseItem warehouseItem : warehouse.sortItemList()){
                warehouseStockService.afterCancelCompletion(warehouse.getWarehouseType(), warehouseItem);
            }
        }


        //已收款,撤消
        Map<String, Object> params = new HashMap<>();
        params.put("warehouseId", warehouse.getId());
        params.put("enterpriseId", warehouse.getEnterpriseId());

        List<Receivable> receivableList = receivableService.selectList(params);
        for (Receivable receivable:receivableList) {
            if (receivable.getAmountPaid().compareTo(BigDecimal.ZERO)>0) {
                throw new CustomException("已收款不能关闭");
            }
            receivableService.delete(receivable);

        }

        //关闭送货单
        if (warehouse.getWarehouseType().equals(4)) {
            List<Shipping> shippingList = shippingService.selectList(params);
            for (Shipping shipping : shippingList) {
                if (shipping.getShippingStatus().equals(3) || shipping.getShippingStatus().equals(4)) {
                    throw new CustomException("已送达不能关闭");
                }
                shippingService.cancel(shipping.getId());
            }
        }

        //关闭退货单
        if (warehouse.getWarehouseType().equals(5)) {
            List<Return> returnList = returnService.selectList(params);
            for (Return returns : returnList) {
                if (returns.getShippingStatus().equals(3) || returns.getShippingStatus().equals(4)) {
                    throw new CustomException("已退货不能关闭");
                }
                returnService.cancel(returns.getId());
            }
        }

        return affectCount;
    }

    private void initWarehouseItem(WarehouseItem warehouseItem){
        Product product = productService.selectByPrimaryKey(warehouseItem.getProductId());
        warehouseItem.setSn(product.getSn());
        if (product.getCost()==null) {
            warehouseItem.setCost(product.getCost());
        }
        warehouseItem.setName(product.getName());
        if (product.getSpec1()==null) {
            product.setSpec1("");
        }
        if (product.getSpec2()==null) {
            product.setSpec2("");
        }
        warehouseItem.setThumbnail(product.getThumbnail());
        warehouseItem.setSubType(product.getSubType());

        warehouseItem.setSpec(product.getSpec1()+product.getSpec2());
        warehouseItem.setUnit(product.getUnit());

        if (null == warehouseItem.getDiscount()){
            warehouseItem.setDiscount(BigDecimal.ZERO);
        }

        if (null == warehouseItem.getTax()){
            warehouseItem.setTax(BigDecimal.ZERO);
        }


    }

    /**
     * 生成送货单
     * @param warehouse
     */
    @Transactional(rollbackFor = Exception.class)
    public void insertShipping(Warehouse warehouse,String sn){

        if (!warehouse.getWarehouseType().equals(WarehouseTypeEnum.WAREHOUSE_TYPE_SALE_OUT.getId())) {
            throw new CustomException("不能生成送货单");
        }

        List<WarehouseItem> sourceOrderItemList = warehouseItemService.getItemList(warehouse.getId());

        Long supplierId = 0L;
        Shipping shipping = new Shipping();

        List<ShippingItem> itemsList = new ArrayList<>();
        Integer w = 1;
        for (WarehouseItem orderItem:sourceOrderItemList) {
            Product product = productService.selectByPrimaryKey(orderItem.getProductId());
            if (!orderItem.getSubType().equals(0) && !orderItem.getSubType().equals(4)) {
                continue;
            }

            if (product.getSupplierId()==null) {
                product.setSupplierId(0L);
            }

            if (!product.getSupplierId().equals(supplierId) && itemsList.size()>0) {
                shippingService.insertUseGeneratedKeys(shipping);
                shipping = new Shipping();
                itemsList.clear();
                w++;
            }
            supplierId = product.getSupplierId();

            shipping.setSn(sn+"-"+String.valueOf(w));
            shipping.setAddress(warehouse.getAddress());
            shipping.setAreaName(warehouse.getAreaName());
            shipping.setConsignee(warehouse.getConsignee());
            shipping.setPhone(warehouse.getPhone());
            shipping.setMemo(warehouse.getMemo());

            //默认已派单
            shipping.setOrderDate(warehouse.getOrderDate());
            shipping.setWarehouseId(warehouse.getId());
            shipping.setShippingStatus(1);
            shipping.setMemberId(warehouse.getMemberId());
            shipping.setOrderId(warehouse.getOrderId());
            shipping.setEnterpriseId(warehouse.getEnterpriseId());
            shipping.setShopId(warehouse.getShopId());
            shipping.setOrderSn(warehouse.getOrderSn());

            shipping.setSupplierId(product.getSupplierId());
            shipping.setShippingMethod(warehouse.getShippingMethod());

            shipping.setTaxType(warehouse.getTaxType());
            shipping.setLevel(0);
            shipping.setShippingFreight(BigDecimal.ZERO);
            shipping.setAdminFreight(BigDecimal.ZERO);
            shipping.setLevelFreight(BigDecimal.ZERO);
            shipping.setSubPrice(orderItem.getSubTotal());
            shipping.setSubQuantity(orderItem.getQuantity());
            shipping.setDeleted(false);
            shipping.setOfficeId(warehouse.getOfficeId());
            shipping.setSPrint(0);
            shipping.setAskforId(warehouse.getAskforId());
            shipping.setOrderPlanId(warehouse.getOrderPlanId());

            ShippingItem shippingItem = new ShippingItem();
            shippingItem.setSubType(orderItem.getSubType());
            shippingItem.setCost(orderItem.getCost());
            shippingItem.setName(orderItem.getName());
            shippingItem.setPrice(orderItem.getPrice());
            shippingItem.setDiscount(orderItem.getDiscount());
            shippingItem.setQuantity(orderItem.getQuantity());
            shippingItem.setSn(orderItem.getSn());
            shippingItem.setAdminFreight(BigDecimal.ZERO);
            shippingItem.setShippingFreight(BigDecimal.ZERO);
            shippingItem.setLevelFreight(BigDecimal.ZERO);
            shippingItem.setSpec(orderItem.getSpec());
            shippingItem.setThumbnail(orderItem.getThumbnail());
            shippingItem.setProductId(orderItem.getProductId());
            shippingItem.setUnit(orderItem.getUnit());
            shippingItem.setEmptyBarrelQuantity(BigDecimal.ZERO);
            //冗余存储
            shippingItem.setEnterpriseId(shipping.getEnterpriseId());
            itemsList.add(shippingItem);

            shipping.setItemList(itemsList);
        }

        if (shipping.getId()==null && itemsList.size()>0) {
            shippingService.insertUseGeneratedKeys(shipping);

            shippingService.print(shipping.getId());
        }

    }

    /**
     * 生成退货单
     * @param warehouse
     */
    @Transactional(rollbackFor = Exception.class)
    public Return insertReturn(Warehouse warehouse,String sn){

        if (!warehouse.getWarehouseType().equals(WarehouseTypeEnum.WAREHOUSE_TYPE_SALE_IN.getId())) {
            throw new CustomException("不能生成退货单");
        }

        List<WarehouseItem> sourceOrderItemList = warehouseItemService.getItemList(warehouse.getId());
        Long supplierId = null;
        Return returns = new Return();

        List<ReturnItem> itemsList = new ArrayList<>();
        Integer w = 1;
        for (WarehouseItem orderItem:sourceOrderItemList) {
            Product product = productService.selectByPrimaryKey(orderItem.getProductId());

            if (!orderItem.getSubType().equals(0) && !orderItem.getSubType().equals(4)) {
                continue;
            }

            if (product.getSupplierId()==null) {
                product.setSupplierId(0L);
            }

            if (!product.getSupplierId().equals(supplierId) && itemsList.size()>0) {
                returnService.insertUseGeneratedKeys(returns);
                returns = new Return();
                itemsList.clear();
                w++;
            }

            supplierId = product.getSupplierId();
            returns.setSn(sn+"-"+String.valueOf(w));
            returns.setAddress(warehouse.getAddress());
            returns.setAreaName(warehouse.getAreaName());
            returns.setConsignee(warehouse.getConsignee());
            returns.setPhone(warehouse.getPhone());
            returns.setMemo(warehouse.getMemo());

            //默认已派单
            returns.setOrderDate(warehouse.getOrderDate());
            returns.setShippingStatus(ShippingStatusEnum.SHIPPING_STATUS_DISPATCH.getId());
            returns.setWarehouseId(warehouse.getId());
            returns.setMemberId(warehouse.getMemberId());
            returns.setOrderId(warehouse.getOrderId());
            returns.setOrderSn(warehouse.getOrderSn());

            returns.setEnterpriseId(warehouse.getEnterpriseId());
            returns.setShopId(warehouse.getShopId());

            returns.setSupplierId(product.getSupplierId());
            returns.setShippingMethod(warehouse.getShippingMethod());

            returns.setTaxType(warehouse.getTaxType());
            returns.setLevel(0);
            returns.setShippingFreight(BigDecimal.ZERO);
            returns.setAdminFreight(BigDecimal.ZERO);
            returns.setLevelFreight(BigDecimal.ZERO);
            returns.setSubPrice(orderItem.getSubTotal());
            returns.setSubQuantity(orderItem.getQuantity());
            returns.setDeleted(false);
            returns.setOfficeId(warehouse.getOfficeId());
            returns.setSPrint(0);
            returns.setAskforId(warehouse.getAskforId());
            returns.setOrderPlanId(warehouse.getOrderPlanId());

            ReturnItem returnItem = new ReturnItem();
            returnItem.setSubType(orderItem.getSubType());
            returnItem.setCost(orderItem.getCost());
            returnItem.setName(orderItem.getName());
            returnItem.setPrice(orderItem.getPrice());
            returnItem.setDiscount(orderItem.getDiscount());
            returnItem.setQuantity(orderItem.getQuantity());
            returnItem.setSn(orderItem.getSn());
            returnItem.setSpec(orderItem.getSpec());
            returnItem.setThumbnail(orderItem.getThumbnail());
            returnItem.setProductId(orderItem.getProductId());
            returnItem.setAdminFreight(BigDecimal.ZERO);
            returnItem.setShippingFreight(BigDecimal.ZERO);
            returnItem.setLevelFreight(BigDecimal.ZERO);
            returnItem.setUnit(orderItem.getUnit());
            returnItem.setEmptyBarrelQuantity(BigDecimal.ZERO);

            itemsList.add(returnItem);

            returns.setItemList(itemsList);

        }

        if (returns.getId()==null && itemsList.size()>0) {
            returnService.insertUseGeneratedKeys(returns);

            return returns;
        } else {
            return null;
        }

    }


    public void sendAllocateMq(Allocate allocate){
        //通过MQ异步处理业务逻辑
        Message message = MessageBuilder
                .withBody(JSON.toJSONString(allocate).getBytes())
                .setContentType(MessageProperties.CONTENT_TYPE_JSON)
                .build();
        CorrelationData correlationData = new CorrelationData();
        correlationData.setId(UUID.randomUUID().toString());
        logger.info("发送 MQ");
        rabbitTemplate.convertAndSend("directExchange","queue.allocate.audit.key", message, correlationData);
    }


    @Transactional(rollbackFor = Exception.class)
    public int insertWareHouseByAllocate(Warehouse param){
        //查询出入库单，按出库单copy生成入库单
        Warehouse warehouse = selectByPrimaryKey(param.getId());
        WarehouseItem itemParam = new WarehouseItem();
        itemParam.setWarehouseId(warehouse.getId());
        List<WarehouseItem> list = warehouseItemService.select(itemParam);
        for (WarehouseItem warehouseItem : list){
            warehouse.setShopId(warehouse.getShopId());
        }
        //查询调拨单的入库门店
        Allocate allocate = allocateService.selectByPrimaryKey(param.getOrderId());

        Warehouse target = new Warehouse();
        BeanUtils.copyProperties(warehouse, target);
        target.setWarehouseType(WarehouseTypeEnum.WAREHOUSE_TYPE_ALLOCATE_IN.getId());
        target.setSn(sysSequenceService.generate("order"));
        target.setShopId(allocate.getInShopId());
        target.setStatus(WarehouseStatusEnum.WAREHOUSE_STATUS_UNCONFIRM.getId());
        target.setItemList(list);

        return this.insertUseGeneratedKeys(target);
    }


    /**
     * 出入库单据确认时调用，回写各种单据的发货、退货数量
     * @param warehouse
     */
    @Transactional(rollbackFor = Exception.class)
    public void writeOrderQuantity(Warehouse warehouse){
        if (warehouse.getOrderPlanId()!=null) {
            return;
        }
        WarehouseTypeEnum warehouseTypeEnum = WarehouseTypeEnum.getById(warehouse.getWarehouseType());
        WarehouseItem param2 = new WarehouseItem();
        param2.setWarehouseId(warehouse.getId());
        List<WarehouseItem> warehouseItemList = warehouseItemService.select(param2);
        switch (warehouseTypeEnum) {
            case WAREHOUSE_TYPE_SALE_IN:
                writeSaleInQuantity(warehouse, warehouseItemList);
                break;
            case WAREHOUSE_TYPE_SALE_OUT :
                writeSaleOutQuantity(warehouse, warehouseItemList);
                break;
            case WAREHOUSE_TYPE_PURCHASE_IN:
                //采购入库
                writePurchaseInQuantity(warehouse, warehouseItemList);
                break;
            case WAREHOUSE_TYPE_PURCHASE_OUT:
                //采购出库(退货)
                writePurchaseOutQuantity(warehouse, warehouseItemList);
                break;
            case WAREHOUSE_TYPE_ALLOCATE_OUT :
                writeAllocateOutQuantity(warehouse, warehouseItemList);
                break;
            case WAREHOUSE_TYPE_ALLOCATE_IN:
                writeAllocateInQuantity(warehouse, warehouseItemList);
                break;
            default:
                break;
        }
    }


    @Transactional(rollbackFor = Exception.class)
    public void writeSaleInQuantity(Warehouse warehouse, List<WarehouseItem> warehouseItemList){

        Order order = orderService.selectByPrimaryKey(warehouse.getOrderId());
        OrderItem param = new OrderItem();
        param.setOrderId(order.getId());
        List<OrderItem> orderItemList = orderItemService.select(param);

        //销售退货单
        for (WarehouseItem warehouseItem : warehouseItemList) {
            //本次退货数量
            BigDecimal quantity = warehouseItem.getQuantity();
            for (OrderItem orderItem : orderItemList){
                if (orderItem.getProductId().equals(warehouseItem.getProductId())){
                    //本商品剩余可退货数量
                    BigDecimal canReturnQty = orderItem.getQuantity().subtract(orderItem.getReturnQuantity());
                    BigDecimal returnQuantity = BigDecimal.ZERO;
                    //当可退货数量大于本次退货数量，用本次退货数量
                    if (canReturnQty.compareTo(quantity) >= 0){
                        returnQuantity = quantity;
                        orderItem.setReturnQuantity(returnQuantity.add(orderItem.getReturnQuantity()));
                        orderItemService.updateByPrimaryKeySelective(orderItem);
                    }else{
                        //当可发货数量小于本次发货数量，用商品可发货数量，当前商品剩余未发货数量继续循环
                        returnQuantity = canReturnQty;
                        orderItem.setReturnQuantity(returnQuantity.add(orderItem.getReturnQuantity()));
                        orderItemService.updateByPrimaryKeySelective(orderItem);
                    }
                    //剩余退货数量
                    quantity = quantity.subtract(returnQuantity);
                }
            }
//            if (quantity.compareTo(BigDecimal.ZERO) != 0){
//                throw new CustomException("退货数量不能大于订货数量,请核对!");
//            }
        }
        //发货数量 大于等于 订单商品数量，更新订单的货运状态 (商品全退的情况下才更新“已退货”)
        BigDecimal returnedQuantity = BigDecimal.ZERO;
        BigDecimal shippingQuantity = BigDecimal.ZERO;
        for (OrderItem orderItem:orderItemList) {
            returnedQuantity = returnedQuantity.add(orderItem.getReturnQuantity());
            shippingQuantity = shippingQuantity.add(orderItem.getShippedQuantity()).add(orderItem.getReturnQuantity());
        }
        if (returnedQuantity.compareTo(order.getSubQuantity())>=0) {
            order.setShippingStatus(OrderShippingStatusEnum.SHIPPING_STATUS_REFUND_SHIPPING.getId());
        }else{
            //当是部分退的时候，还是要当做出库库处理，shippingQuantity包含了退货数量
            if (shippingQuantity.compareTo(order.getSubQuantity())>=0) {
                order.setShippingStatus(OrderShippingStatusEnum.SHIPPING_STATUS_SHIPPNG.getId());
            }
        }
        orderService.updateByPrimaryKeySelective(order);
    }

    @Transactional(rollbackFor = Exception.class)
    public void writeSaleOutQuantity(Warehouse warehouse, List<WarehouseItem> warehouseItemList){
        Order order = orderService.selectByPrimaryKey(warehouse.getOrderId());
        OrderItem param = new OrderItem();
        param.setOrderId(order.getId());
        List<OrderItem> orderItemList = orderItemService.select(param);

        for (WarehouseItem warehouseItem : warehouseItemList) {
            //本次发货数量
            BigDecimal quantity = warehouseItem.getQuantity();
            for (OrderItem orderItem : orderItemList){
                if (orderItem.getProductId().equals(warehouseItem.getProductId())){
                    //本商品剩余可发货数量
                    BigDecimal canShippingQty = orderItem.getQuantity().subtract(orderItem.getShippedQuantity());
                    BigDecimal shippingQuantity = BigDecimal.ZERO;
                    //当可发货数量大于本次发货数量，用本次发货数量
                    if (canShippingQty.compareTo(quantity) >= 0){
                        shippingQuantity = quantity;
                        orderItem.setShippedQuantity(shippingQuantity.add(orderItem.getShippedQuantity()));
                        orderItemService.updateByPrimaryKeySelective(orderItem);
                    }else{
                        //当可发货数量小于本次发货数量，用商品可发货数量，当前商品剩余未发货数量继续循环
                        shippingQuantity = canShippingQty;
                        orderItem.setShippedQuantity(shippingQuantity.add(orderItem.getShippedQuantity()));
                        orderItemService.updateByPrimaryKeySelective(orderItem);
                    }
                    //剩余发货数量
                    quantity = quantity.subtract(shippingQuantity);
                }
            }
            logger.info("计算之后的发货、退货数量 ===={}", quantity);
//            if (quantity.compareTo(BigDecimal.ZERO) != 0){
//                throw new CustomException("发货数量不能大于订货数量,请核对!");
//            }

            //发货数量 大于等于 订单商品数量，更新订单的货运状态
            BigDecimal shippingQuantity = BigDecimal.ZERO;
            for (OrderItem orderItem:orderItemList) {
                shippingQuantity = shippingQuantity.add(orderItem.getShippedQuantity()).add(orderItem.getReturnQuantity());
            }
            if (shippingQuantity.compareTo(order.getSubQuantity())>=0) {
                order.setShippingStatus(OrderShippingStatusEnum.SHIPPING_STATUS_SHIPPNG.getId());
            }
            orderService.updateByPrimaryKeySelective(order);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void writePurchaseInQuantity(Warehouse warehouse, List<WarehouseItem> warehouseItemList){
        Purchase purchase = purchaseService.selectByPrimaryKey(warehouse.getOrderId());
        PurchaseItem param = new PurchaseItem();
        param.setPurchaseId(purchase.getId());
        List<PurchaseItem> purchaseItemList = purchaseItemService.select(param);
        //采购入库单
        for (WarehouseItem warehouseItem : warehouseItemList) {
            //本次入库数量
            BigDecimal quantity = warehouseItem.getQuantity();
            for (PurchaseItem purchaseItem : purchaseItemList){
                if (purchaseItem.getProductId().equals(warehouseItem.getProductId())){
                    //本商品剩余可入库数量 = 订单数量 - 已入库数量 (与退货数量无关)
                    BigDecimal canInStockQty = purchaseItem.getQuantity().subtract(purchaseItem.getStockQuantity());
                    BigDecimal inStockQuantity = BigDecimal.ZERO;
                    //当可发货数量大于本次发货数量，用本次发货数量
                    if (canInStockQty.compareTo(quantity) >= 0){
                        inStockQuantity = quantity;
                        purchaseItem.setStockQuantity(inStockQuantity.add(purchaseItem.getStockQuantity()));
                        purchaseItemService.updateByPrimaryKeySelective(purchaseItem);
                    }else{
                        //当可发货数量小于本次发货数量，用本次可发货数量，当前商品剩余未发货数量继续循环
                        inStockQuantity = canInStockQty;
                        purchaseItem.setStockQuantity(inStockQuantity.add(purchaseItem.getStockQuantity()));
                        purchaseItemService.updateByPrimaryKeySelective(purchaseItem);
                    }
                    //剩余可入库数量
                    quantity = quantity.subtract(inStockQuantity);
                }
            }
//            if (quantity.compareTo(BigDecimal.ZERO) != 0){
//                throw new CustomException("入库数量不能大于订货数量,请核对!");
//            }
        }
        //更新采购订单状态
        //入库数量 大于等于 订单商品数量，更新订单的货运状态
        BigDecimal stockQuantity = BigDecimal.ZERO;
        for (PurchaseItem purchaseItem: purchaseItemList) {
            stockQuantity = stockQuantity.add(purchaseItem.getStockQuantity()).add(purchaseItem.getReturnQuantity());
        }
        logger.info("stockQuantity ===== [{}]", stockQuantity);
        logger.info("purchase.getSubQuantity() ===== [{}]", purchase.getSubQuantity());
        if (stockQuantity.compareTo(purchase.getSubQuantity())>=0) {
            purchase.setShippingStatus(PurchaseShippingStatusEnum.SHIPPING_STATUS_SHIPPNG.getId());
            purchase.setOrderStatus(PurchaseOrderStatusEnum.ORDER_STATUS_COMPLETE.getId());
        }
        purchaseService.updateByPrimaryKeySelective(purchase);
    }


    @Transactional(rollbackFor = Exception.class)
    public void writePurchaseOutQuantity(Warehouse warehouse, List<WarehouseItem> warehouseItemList){
        Purchase purchase = purchaseService.selectByPrimaryKey(warehouse.getOrderId());
        PurchaseItem param = new PurchaseItem();
        param.setPurchaseId(purchase.getId());
        List<PurchaseItem> purchaseItemList = purchaseItemService.select(param);
        //采购退货单
        for (WarehouseItem warehouseItem : warehouseItemList) {
            //本次退货数量
            BigDecimal quantity = warehouseItem.getQuantity();
            for (PurchaseItem purchaseItem : purchaseItemList){
                if (purchaseItem.getProductId().equals(warehouseItem.getProductId())){
                    //本商品剩余可退货数量 = 已入库数量 - 已退货数量
                    BigDecimal canOutStockQty = purchaseItem.getStockQuantity().subtract(purchaseItem.getReturnQuantity());
                    BigDecimal outStockQuantity = BigDecimal.ZERO;
                    if (canOutStockQty.compareTo(quantity) >= 0){
                        outStockQuantity = quantity;
                        purchaseItem.setReturnQuantity(outStockQuantity.add(purchaseItem.getReturnQuantity()));
                        purchaseItemService.updateByPrimaryKeySelective(purchaseItem);
                    }else{
                        //当可退货数量小于本次退货数量，用本次可退货数量，当前商品剩余未发货数量继续循环
                        outStockQuantity = canOutStockQty;
                        purchaseItem.setReturnQuantity(outStockQuantity.add(purchaseItem.getReturnQuantity()));
                        purchaseItemService.updateByPrimaryKeySelective(purchaseItem);
                    }
                    //剩余可退货数量
                    quantity = quantity.subtract(outStockQuantity);
                }
            }
//            if (quantity.compareTo(BigDecimal.ZERO) != 0){
//                throw new CustomException("退货数量不能大于可退数量,请核对!");
//            }
        }
        //更新采购订单状态
        //退货数量 大于等于 订单商品数量，更新订单的货运状态
        BigDecimal returnQuantity = BigDecimal.ZERO;
        BigDecimal stockQuantity = BigDecimal.ZERO;
        for (PurchaseItem purchaseItem: purchaseItemList) {
            returnQuantity = returnQuantity.add(purchaseItem.getReturnQuantity());
//            stockQuantity = stockQuantity.add(purchaseItem.getStockQuantity()).add(purchaseItem.getReturnQuantity());
            stockQuantity = stockQuantity.add(purchaseItem.getStockQuantity());
        }
        logger.info("returnQuantity ===== [{}]", returnQuantity);
        logger.info("stockQuantity ===== [{}]", stockQuantity);
        logger.info("purchase.getSubQuantity() ===== [{}]", purchase.getSubQuantity());
        if (returnQuantity.compareTo(purchase.getSubQuantity())>=0) {
            purchase.setShippingStatus(PurchaseShippingStatusEnum.SHIPPING_STATUS_REFUND_SHIPPING.getId());
            purchase.setOrderStatus(PurchaseOrderStatusEnum.ORDER_STATUS_COMPLETE.getId());
        }else{
            //当是部分退的时候，还是要当做入库处理，stockQuantity包含了退货数量
            if (stockQuantity.compareTo(purchase.getSubQuantity())>=0) {
                purchase.setShippingStatus(PurchaseShippingStatusEnum.SHIPPING_STATUS_SHIPPNG.getId());
                purchase.setOrderStatus(PurchaseOrderStatusEnum.ORDER_STATUS_COMPLETE.getId());
            }else{
                purchase.setShippingStatus(PurchaseShippingStatusEnum.SHIPPING_STATUS_UNSHIPPNG.getId());
                purchase.setOrderStatus(PurchaseOrderStatusEnum.ORDER_STATUS_CONFIRM.getId());
            }
        }
        purchaseService.updateByPrimaryKeySelective(purchase);
    }


    @Transactional(rollbackFor = Exception.class)
    public void writeAllocateOutQuantity(Warehouse warehouse, List<WarehouseItem> warehouseItemList){
        Allocate allocate = allocateService.selectByPrimaryKey(warehouse.getOrderId());
        AllocateItem param = new AllocateItem();
        param.setAllocateId(allocate.getId());
        List<AllocateItem> allocateItemList = allocateItemService.select(param);
        //调拨出库，一次性发货
        for (WarehouseItem warehouseItem : warehouseItemList) {
            //本次出库数量
            BigDecimal quantity = warehouseItem.getQuantity();
            for (AllocateItem allocateItem : allocateItemList){
                if (allocateItem.getProductId().equals(warehouseItem.getProductId())){
                    allocateItem.setShippedQuantity(quantity);
                    allocateItemService.updateByPrimaryKeySelective(allocateItem);
                }
            }
        }
        allocate.setShippingStatus(AllocateShippingStatusEnum.ALLOCATE_SHIPPING_HAS_OUT.getId());
        allocateService.updateByPrimaryKeySelective(allocate);
    }

    @Transactional(rollbackFor = Exception.class)
    public void writeAllocateInQuantity(Warehouse warehouse, List<WarehouseItem> warehouseItemList){
        Allocate allocate = allocateService.selectByPrimaryKey(warehouse.getOrderId());
        AllocateItem param = new AllocateItem();
        param.setAllocateId(allocate.getId());
        List<AllocateItem> allocateItemList = allocateItemService.select(param);
        //调拨入库
        for (WarehouseItem warehouseItem : warehouseItemList) {
            //本次入库数量
            BigDecimal quantity = warehouseItem.getQuantity();
            for (AllocateItem allocateItem : allocateItemList){
                if (allocateItem.getProductId().equals(warehouseItem.getProductId())){
                    allocateItem.setReceiviedQuantity(quantity);
                    allocateItemService.updateByPrimaryKeySelective(allocateItem);
                }
            }
        }
        allocate.setShippingStatus(AllocateShippingStatusEnum.ALLOCATE_SHIPPING_HAS_IN.getId());
        allocate.setOrderStatus(AllocateStatusEnum.ALLOCATE_STATUS_COMPLETE.getId());
        allocateService.updateByPrimaryKeySelective(allocate);
    }


    /**
     * 出入库单据作废时调用，退回各种单据的发货、退货数量
     * @param warehouse
     */
    @Transactional(rollbackFor = Exception.class)
    public void undoWriteOrderQuantity(Warehouse warehouse){
        if (warehouse.getOrderPlanId()!=null) {
            return;
        }
        WarehouseTypeEnum warehouseTypeEnum = WarehouseTypeEnum.getById(warehouse.getWarehouseType());
        WarehouseItem param2 = new WarehouseItem();
        param2.setWarehouseId(warehouse.getId());
        List<WarehouseItem> warehouseItemList = warehouseItemService.select(param2);
        switch (warehouseTypeEnum) {
            case WAREHOUSE_TYPE_SALE_IN:
                undoWriteSaleInQuantity(warehouse, warehouseItemList);
                break;
            case WAREHOUSE_TYPE_SALE_OUT :
                undoWriteSaleOutQuantity(warehouse, warehouseItemList);
                break;
            case WAREHOUSE_TYPE_PURCHASE_IN:
                //采购入库
                undoWritePurchaseInQuantity(warehouse, warehouseItemList);
                break;
            case WAREHOUSE_TYPE_PURCHASE_OUT:
                //采购出库(退货)
                undoWritePurchaseOutQuantity(warehouse, warehouseItemList);
                break;
            case WAREHOUSE_TYPE_ALLOCATE_OUT :
                //调拨出库
                undoWriteAllocateOutQuantity(warehouse, warehouseItemList);
                break;
            case WAREHOUSE_TYPE_ALLOCATE_IN:
                //调拨入库
                undoWriteAllocateInQuantity(warehouse, warehouseItemList);
                break;
            default:
                break;
        }
    }


    @Transactional(rollbackFor = Exception.class)
    public void undoWriteSaleInQuantity(Warehouse warehouse, List<WarehouseItem> warehouseItemList){
        Order order = orderService.selectByPrimaryKey(warehouse.getOrderId());
        OrderItem param = new OrderItem();
        param.setOrderId(order.getId());
        List<OrderItem> orderItemList = orderItemService.select(param);

        //销售退货单
        for (WarehouseItem warehouseItem : warehouseItemList) {
            //本次返回数量
            BigDecimal quantity = warehouseItem.getQuantity();
            for (OrderItem orderItem : orderItemList){
                if (orderItem.getProductId().equals(warehouseItem.getProductId())){
                    //本商品剩余可返回数量
                    BigDecimal canReturnQty = orderItem.getReturnQuantity();
                    BigDecimal returnQuantity = BigDecimal.ZERO;
                    //当可退货数量大于本次退货数量，用本次退货数量
                    if (canReturnQty.compareTo(quantity) >= 0){
                        returnQuantity = quantity;
                        orderItem.setReturnQuantity(orderItem.getReturnQuantity().subtract(returnQuantity));
                        orderItemService.updateByPrimaryKeySelective(orderItem);
                    }else{
                        //当可发货数量小于本次发货数量，用商品可发货数量，当前商品剩余未发货数量继续循环
                        returnQuantity = canReturnQty;
                        orderItem.setReturnQuantity(orderItem.getReturnQuantity().subtract(returnQuantity));
                        orderItemService.updateByPrimaryKeySelective(orderItem);
                    }
                    //剩余返回数量
                    quantity = quantity.subtract(returnQuantity);
                }
            }
//            if (quantity.compareTo(BigDecimal.ZERO) != 0){
//                throw new CustomException("退货数量不能大于订货数量,请核对!");
//            }
        }

        //发货数量 大于等于 订单商品数量，更新订单的货运状态 (商品全退的情况下才更新“已退货”)
        BigDecimal returnedQuantity = BigDecimal.ZERO;
        BigDecimal shippingQuantity = BigDecimal.ZERO;
        for (OrderItem orderItem:orderItemList) {
            returnedQuantity = returnedQuantity.add(orderItem.getReturnQuantity());
            shippingQuantity = shippingQuantity.add(orderItem.getShippedQuantity()).add(orderItem.getReturnQuantity());
        }

        //更新单据表头
        if (returnedQuantity.compareTo(order.getSubQuantity())>=0) {
            order.setShippingStatus(OrderShippingStatusEnum.SHIPPING_STATUS_REFUND_SHIPPING.getId());
        }else{
            //发货数量大于等于商品数量
            if (shippingQuantity.compareTo(order.getSubQuantity())>=0) {
                order.setShippingStatus(OrderShippingStatusEnum.SHIPPING_STATUS_SHIPPNG.getId());
            }else{
                //发货数量小于商品数量
                order.setShippingStatus(OrderShippingStatusEnum.SHIPPING_STATUS_UNSHIPPNG.getId());
            }
        }
        orderService.updateByPrimaryKeySelective(order);

    }


    @Transactional(rollbackFor = Exception.class)
    public void undoWriteSaleOutQuantity(Warehouse warehouse, List<WarehouseItem> warehouseItemList){
        Order order = orderService.selectByPrimaryKey(warehouse.getOrderId());
        OrderItem param = new OrderItem();
        param.setOrderId(order.getId());
        List<OrderItem> orderItemList = orderItemService.select(param);

        //销售出库单
        for (WarehouseItem warehouseItem : warehouseItemList) {
            //本次返回数量
            BigDecimal quantity = warehouseItem.getQuantity();
            for (OrderItem orderItem : orderItemList){
                if (orderItem.getProductId().equals(warehouseItem.getProductId())){
                    //本商品剩余可返回数量
                    BigDecimal canReturnQty = orderItem.getShippedQuantity();
                    BigDecimal returnQuantity = BigDecimal.ZERO;
                    if (canReturnQty.compareTo(quantity) >= 0){
                        returnQuantity = quantity;
                        orderItem.setShippedQuantity(orderItem.getShippedQuantity().subtract(returnQuantity));
                        orderItemService.updateByPrimaryKeySelective(orderItem);
                    }else{
                        returnQuantity = canReturnQty;
                        orderItem.setShippedQuantity(orderItem.getShippedQuantity().subtract(returnQuantity));
                        orderItemService.updateByPrimaryKeySelective(orderItem);
                    }
                    //剩余返回数量
                    quantity = quantity.subtract(returnQuantity);
                }
            }
//            if (quantity.compareTo(BigDecimal.ZERO) != 0){
//                throw new CustomException("作废退货数量不能大于订货数量,请核对!");
//            }
        }
        //发货数量 大于等于 订单商品数量，更新订单的货运状态 (商品全退的情况下才更新“已退货”)
        BigDecimal returnedQuantity = BigDecimal.ZERO;
        BigDecimal shippingQuantity = BigDecimal.ZERO;
        for (OrderItem orderItem:orderItemList) {
            returnedQuantity = returnedQuantity.add(orderItem.getReturnQuantity());
            shippingQuantity = shippingQuantity.add(orderItem.getShippedQuantity()).add(orderItem.getReturnQuantity());
        }

        //更新单据表头
        if (returnedQuantity.compareTo(order.getSubQuantity())>=0) {
            order.setShippingStatus(OrderShippingStatusEnum.SHIPPING_STATUS_REFUND_SHIPPING.getId());
        }else{
            //发货数量大于等于商品数量
            if (shippingQuantity.compareTo(order.getSubQuantity())>=0) {
                order.setShippingStatus(OrderShippingStatusEnum.SHIPPING_STATUS_SHIPPNG.getId());
            }else{
                //发货数量小于商品数量
                order.setShippingStatus(OrderShippingStatusEnum.SHIPPING_STATUS_UNSHIPPNG.getId());
            }
        }
        orderService.updateByPrimaryKeySelective(order);
    }


    @Transactional(rollbackFor = Exception.class)
    public void undoWritePurchaseInQuantity(Warehouse warehouse, List<WarehouseItem> warehouseItemList){
        Purchase purchase = purchaseService.selectByPrimaryKey(warehouse.getOrderId());
        PurchaseItem param = new PurchaseItem();
        param.setPurchaseId(purchase.getId());
        List<PurchaseItem> purchaseItemList = purchaseItemService.select(param);
        //采购入库单
        for (WarehouseItem warehouseItem : warehouseItemList) {
            //本次返回数量
            BigDecimal quantity = warehouseItem.getQuantity();
            for (PurchaseItem purchaseItem : purchaseItemList){
                if (purchaseItem.getProductId().equals(warehouseItem.getProductId())){
                    BigDecimal canInStockQty = purchaseItem.getStockQuantity();
                    BigDecimal inStockQuantity = BigDecimal.ZERO;
                    //当可发货数量大于本次发货数量，用本次发货数量
                    if (canInStockQty.compareTo(quantity) >= 0){
                        inStockQuantity = quantity;
                        purchaseItem.setStockQuantity(purchaseItem.getStockQuantity().subtract(inStockQuantity));
                        purchaseItemService.updateByPrimaryKeySelective(purchaseItem);
                    }else{
                        inStockQuantity = canInStockQty;
                        purchaseItem.setStockQuantity(purchaseItem.getStockQuantity().subtract(inStockQuantity));
                        purchaseItemService.updateByPrimaryKeySelective(purchaseItem);
                    }
                    quantity = quantity.subtract(inStockQuantity);
                }
            }
//            if (quantity.compareTo(BigDecimal.ZERO) != 0){
//                throw new CustomException("作废入库数量不能大于订货数量,请核对!");
//            }
        }
        //更新采购订单状态
        //入库数量 大于等于 订单商品数量，更新订单的货运状态
        BigDecimal stockQuantity = BigDecimal.ZERO;
        BigDecimal returnedQuantity = BigDecimal.ZERO;
        for (PurchaseItem purchaseItem: purchaseItemList) {
            stockQuantity = stockQuantity.add(purchaseItem.getStockQuantity()).add(purchaseItem.getReturnQuantity());
            returnedQuantity = returnedQuantity.add(purchaseItem.getReturnQuantity());
        }
        //更新单据表头
        if (returnedQuantity.compareTo(purchase.getSubQuantity())>=0) {
            purchase.setShippingStatus(PurchaseShippingStatusEnum.SHIPPING_STATUS_REFUND_SHIPPING.getId());
            purchase.setOrderStatus(PurchaseOrderStatusEnum.ORDER_STATUS_COMPLETE.getId());
        }else{
            if (stockQuantity.compareTo(purchase.getSubQuantity())>=0) {
                purchase.setShippingStatus(PurchaseShippingStatusEnum.SHIPPING_STATUS_SHIPPNG.getId());
                purchase.setOrderStatus(PurchaseOrderStatusEnum.ORDER_STATUS_COMPLETE.getId());
            }else{
                //发货数量小于商品数量
                purchase.setShippingStatus(PurchaseShippingStatusEnum.SHIPPING_STATUS_UNSHIPPNG.getId());
                purchase.setOrderStatus(PurchaseOrderStatusEnum.ORDER_STATUS_CONFIRM.getId());
            }
        }
        purchaseService.updateByPrimaryKeySelective(purchase);
    }


    @Transactional(rollbackFor = Exception.class)
    public void undoWritePurchaseOutQuantity(Warehouse warehouse, List<WarehouseItem> warehouseItemList){
        Purchase purchase = purchaseService.selectByPrimaryKey(warehouse.getOrderId());
        PurchaseItem param = new PurchaseItem();
        param.setPurchaseId(purchase.getId());
        List<PurchaseItem> purchaseItemList = purchaseItemService.select(param);
        //采购退货单
        for (WarehouseItem warehouseItem : warehouseItemList) {
            //本次退货数量
            BigDecimal quantity = warehouseItem.getQuantity();
            for (PurchaseItem purchaseItem : purchaseItemList){
                if (purchaseItem.getProductId().equals(warehouseItem.getProductId())){
                    BigDecimal canReturnQuantity = purchaseItem.getReturnQuantity();
                    BigDecimal returnQuantity = BigDecimal.ZERO;
                    if (canReturnQuantity.compareTo(quantity) >= 0){
                        returnQuantity = quantity;
                        purchaseItem.setReturnQuantity(purchaseItem.getReturnQuantity().subtract(returnQuantity));
                        purchaseItemService.updateByPrimaryKeySelective(purchaseItem);
                    }else{
                        //当可退货数量小于本次退货数量，用本次可退货数量，当前商品剩余未发货数量继续循环
                        returnQuantity = canReturnQuantity;
                        purchaseItem.setReturnQuantity(purchaseItem.getReturnQuantity().subtract(returnQuantity));
                        purchaseItemService.updateByPrimaryKeySelective(purchaseItem);
                    }
                    //剩余可退货数量
                    quantity = quantity.subtract(returnQuantity);
                }
            }
//            if (quantity.compareTo(BigDecimal.ZERO) != 0){
//                throw new CustomException("退货数量不能大于可退数量,请核对!");
//            }
        }
        //更新采购订单状态
        BigDecimal returnQuantity = BigDecimal.ZERO;
        BigDecimal stockQuantity = BigDecimal.ZERO;
        for (PurchaseItem purchaseItem: purchaseItemList) {
            returnQuantity = returnQuantity.add(purchaseItem.getReturnQuantity());
//            stockQuantity = stockQuantity.add(purchaseItem.getStockQuantity()).add(purchaseItem.getReturnQuantity());
            stockQuantity = stockQuantity.add(purchaseItem.getStockQuantity());
        }
        logger.info("returnQuantity ===== [{}]", returnQuantity);
        logger.info("stockQuantity ===== [{}]", stockQuantity);
        logger.info("purchase.getSubQuantity() ===== [{}]", purchase.getSubQuantity());
        if (returnQuantity.compareTo(purchase.getSubQuantity())>=0) {
            purchase.setShippingStatus(PurchaseShippingStatusEnum.SHIPPING_STATUS_REFUND_SHIPPING.getId());
            purchase.setOrderStatus(PurchaseOrderStatusEnum.ORDER_STATUS_COMPLETE.getId());
        }else{
            //当是部分退的时候，还是要当做入库处理，stockQuantity包含了退货数量
            if (stockQuantity.compareTo(purchase.getSubQuantity())>=0) {
                purchase.setShippingStatus(PurchaseShippingStatusEnum.SHIPPING_STATUS_SHIPPNG.getId());
                purchase.setOrderStatus(PurchaseOrderStatusEnum.ORDER_STATUS_COMPLETE.getId());
            }else{
                purchase.setShippingStatus(PurchaseShippingStatusEnum.SHIPPING_STATUS_UNSHIPPNG.getId());
                purchase.setOrderStatus(PurchaseOrderStatusEnum.ORDER_STATUS_CONFIRM.getId());
            }
        }
        purchaseService.updateByPrimaryKeySelective(purchase);
    }



    @Transactional(rollbackFor = Exception.class)
    public void undoWriteAllocateOutQuantity(Warehouse warehouse, List<WarehouseItem> warehouseItemList){
        Allocate allocate = allocateService.selectByPrimaryKey(warehouse.getOrderId());
        AllocateItem param = new AllocateItem();
        param.setAllocateId(allocate.getId());
        List<AllocateItem> allocateItemList = allocateItemService.select(param);
        //调拨出库
        for (WarehouseItem warehouseItem : warehouseItemList) {
            //本次退货数量
            BigDecimal quantity = warehouseItem.getQuantity();
            for (AllocateItem allocateItem : allocateItemList){
                if (allocateItem.getProductId().equals(warehouseItem.getProductId())){
                    BigDecimal canReturnQuantity = allocateItem.getShippedQuantity();
                    BigDecimal returnQuantity = BigDecimal.ZERO;
                    if (canReturnQuantity.compareTo(quantity) >= 0){
                        returnQuantity = quantity;
                        allocateItem.setShippedQuantity(allocateItem.getShippedQuantity().subtract(returnQuantity));
                        allocateItemService.updateByPrimaryKeySelective(allocateItem);
                    }else{
                        //当可退货数量小于本次退货数量，用本次可退货数量，当前商品剩余未发货数量继续循环
                        returnQuantity = canReturnQuantity;
                        allocateItem.setShippedQuantity(allocateItem.getShippedQuantity().subtract(returnQuantity));
                        allocateItemService.updateByPrimaryKeySelective(allocateItem);
                    }
                    //剩余可退货数量
                    quantity = quantity.subtract(returnQuantity);
                }
            }
//            if (quantity.compareTo(BigDecimal.ZERO) != 0){
//                throw new CustomException("退货数量不能大于可退数量,请核对!");
//            }
        }
        /**
         * 调拨出库，不需要更新调拨单表头
         */
    }


    @Transactional(rollbackFor = Exception.class)
    public void undoWriteAllocateInQuantity(Warehouse warehouse, List<WarehouseItem> warehouseItemList){
        Allocate allocate = allocateService.selectByPrimaryKey(warehouse.getOrderId());
        AllocateItem param = new AllocateItem();
        param.setAllocateId(allocate.getId());
        List<AllocateItem> allocateItemList = allocateItemService.select(param);
        //调拨入库
        for (WarehouseItem warehouseItem : warehouseItemList) {
            //本次退货数量
            BigDecimal quantity = warehouseItem.getQuantity();
            for (AllocateItem allocateItem : allocateItemList){
                if (allocateItem.getProductId().equals(warehouseItem.getProductId())){
                    BigDecimal canReturnQuantity = allocateItem.getReceiviedQuantity();
                    BigDecimal returnQuantity = BigDecimal.ZERO;
                    if (canReturnQuantity.compareTo(quantity) >= 0){
                        returnQuantity = quantity;
                        allocateItem.setReceiviedQuantity(allocateItem.getReceiviedQuantity().subtract(returnQuantity));
                        allocateItemService.updateByPrimaryKeySelective(allocateItem);
                    }else{
                        returnQuantity = canReturnQuantity;
                        allocateItem.setReceiviedQuantity(allocateItem.getReceiviedQuantity().subtract(returnQuantity));
                        allocateItemService.updateByPrimaryKeySelective(allocateItem);
                    }
                    //剩余可退货数量
                    quantity = quantity.subtract(returnQuantity);
                }
            }
//            if (quantity.compareTo(BigDecimal.ZERO) != 0){
//                throw new CustomException("退货数量不能大于可退数量,请核对!");
//            }
        }
        //更新采购订单状态
        BigDecimal shippingQuantity = BigDecimal.ZERO;
        BigDecimal receiviedQuantity = BigDecimal.ZERO;
        BigDecimal quantity = BigDecimal.ZERO;
        for (AllocateItem allocateItem : allocateItemList) {
            quantity = quantity.add(allocateItem.getQuantity());
            shippingQuantity = shippingQuantity.add(allocateItem.getShippedQuantity());
            receiviedQuantity = receiviedQuantity.add(allocateItem.getReceiviedQuantity());
        }
        if (receiviedQuantity.compareTo(quantity)>=0) {
            allocate.setShippingStatus(AllocateShippingStatusEnum.ALLOCATE_SHIPPING_HAS_IN.getId());
            allocate.setOrderStatus(AllocateStatusEnum.ALLOCATE_STATUS_COMPLETE.getId());
        }else{
            if (shippingQuantity.compareTo(quantity)>=0) {
                allocate.setShippingStatus(AllocateShippingStatusEnum.ALLOCATE_SHIPPING_HAS_OUT.getId());
                allocate.setOrderStatus(AllocateStatusEnum.ALLOCATE_STATUS_CONFIRM.getId());
            }else{
                allocate.setShippingStatus(AllocateShippingStatusEnum.ALLOCATE_SHIPPING_WAIT_OUT.getId());
                allocate.setOrderStatus(AllocateStatusEnum.ALLOCATE_STATUS_CONFIRM.getId());
            }
        }
        allocateService.updateByPrimaryKeySelective(allocate);
    }
}
